# 1)	应用程序初始化
# 应用程序应能够成功加载并初始化Flask服务器。
from flask import Flask,request,render_template
from tensorflow.keras.preprocessing.image import load_img,img_to_array
import numpy as np
import os
# 应用程序应加载预训练的AlexNet模型及其权重，模型应针对CIFAR-100数据集进行训练。
from model import AlexNet
alex = AlexNet()
alex.build(input_shape=(None,32,32,3))
alex.load_weights('model.h5')
app = Flask(__name__,template_folder='.')
# 2)	主页显示
# 应用程序应提供一个主页（/路由），该页面包含上传图像的表单。
# 主页应渲染home.html模板，该模板包含文件上传控件和提交按钮。
@app.route('/')
def home():
    return render_template('home.html')
# 3)	图像上传
# 应用程序应能够接收通过POST请求上传的图像文件。
# 上传的文件应保存在服务器上的指定目录（例如static/images）中。
# 4)	图像预测
# 应用程序应能够读取上传的图像文件，并将其转换为模型可接受的格式（例如，32x32像素，3通道，归一化到[0,1]范围）。
def read_img(path):
    img = load_img(path=path,target_size=(32,32))
    img = img_to_array(img)
    img = img.reshape(-1,32,32,3) / 255
    return img
# 应用程序应使用加载的AlexNet模型对图像进行预测，并获取最可能的类别索引。
# 应用程序应能够将类别索引映射到具体的类别名称（使用提供的product_dict字典）。
@app.route('/predict',methods=['POST'])
def predict():
    file = request.files['file']
    try:
        if file:
            file_name = file.filename
            file_path = os.path.join('static/images',file_name)
            file.save(file_path)
            img = read_img(file_path)
            predict_label = np.argmax(alex.predict(img),axis=-1)
            product_dict = {
                            0: 'apple',
                            1: 'aquarium_fish',
                            2: 'baby',
                            3: 'bear',
                            4: 'beaver',
                            5: 'bed',
                            6: 'bee',
                            7: 'beetle',
                            8: 'bicycle',
                            9: 'bottle',
                            10: 'bowl',
                            11: 'boy',
                            12: 'bridge',
                            13: 'bus',
                            14: 'butterfly',
                            15: 'camel',
                            16: 'can',
                            17: 'castle',
                            18: 'caterpillar',
                            19: 'cattle',
                            20: 'chair',
                            21: 'chimpanzee',
                            22: 'clock',
                            23: 'cloud',
                            24: 'cockroach',
                            25: 'couch',
                            26: 'crab',
                            27: 'crocodile',
                            28: 'cup',
                            29: 'dinosaur',
                            30: 'dolphin',
                            31: 'elephant',
                            32: 'flatfish',
                            33: 'forest',
                            34: 'fox',
                            35: 'girl',
                            36: 'hamster',
                            37: 'house',
                            38: 'kangaroo',
                            39: 'keyboard',
                            40: 'lamp',
                            41: 'lawn_mower',
                            42: 'leopard',
                            43: 'lion',
                            44: 'lizard',
                            45: 'lobster',
                            46: 'man',
                            47: 'maple_tree',
                            48: 'motorcycle',
                            49: 'mountain',
                            50: 'mouse',
                            51: 'mushroom',
                            52: 'oak_tree',
                            53: 'orange',
                            54: 'orchid',
                            55: 'otter',
                            56: 'palm_tree',
                            57: 'pear',
                            58: 'pickup_truck',
                            59: 'pine_tree',
                            60: 'plain',
                            61: 'plate',
                            62: 'poppy',
                            63: 'porcupine',
                            64: 'possum',
                            65: 'rabbit',
                            66: 'raccoon',
                            67: 'ray',
                            68: 'road',
                            69: 'rocket',
                            70: 'rose',
                            71: 'sea',
                            72: 'seal',
                            73: 'shark',
                            74: 'shrew',
                            75: 'skunk',
                            76: 'skyscraper',
                            77: 'snail',
                            78: 'snake',
                            79: 'spider',
                            80: 'squirrel',
                            81: 'streetcar',
                            82: 'sunflower',
                            83: 'sweet_pepper',
                            84: 'table',
                            85: 'tank',
                            86: 'telephone',
                            87: 'television',
                            88: 'tiger',
                            89: 'tractor',
                            90: 'train',
                            91: 'trout',
                            92: 'tulip',
                            93: 'turtle',
                            94: 'wardrobe',
                            95: 'whale',
                            96: 'willow_tree',
                            97: 'wolf',
                            98: 'woman',
                            99: 'worm'
                        }
            res = product_dict[predict_label[0]]
            return render_template('predict.html',user_image=file_path,product=res)
    except Exception as e:
        return str(e)

# 5)	结果显示
# 预测完成后，应用程序应渲染predict.html模板，并传递预测结果（类别名称）和上传的图像路径作为模板变量。
# predict.html模板应显示预测结果和上传的图像。
# 6)	错误处理
# 如果上传的文件不是有效的图像文件或无法读取，应用程序应捕获异常并显示相应的错误消息。
# 如果在预测过程中发生任何错误，应用程序应捕获异常并返回适当的错误响应。
# 7)	调试模式
# 应用程序应支持在调试模式下运行，以便在开发过程中提供详细的错误跟踪和日志信息
app.run(host='0.0.0.0',port=6008,debug=True)